using System;
using System.Text;
using System.Collections.Generic;
using InfoJetSoft.Service.XPath.Tokens;

//CID 0164 //2008.12.13 //Begin
namespace InfoJetSoft.Service.XPath.Exprs
{
	/// <summary>
	/// Summary description for UnionExpr.
	/// </summary>
    public class UnionExpr : IExpr
	{
		private List<IExpr> pathList = null;

		public UnionExpr()
		{
			//
			// TODO: Add constructor logic here
			//
        }

        public List<IExpr> Paths
        {
            get
            {
                return this.pathList;
            }
        }

        public object Evaluate(ExprContext context)
        {
            //CID 0813 //2011.03.01 //Begin
            INodeList nodeList = context.Calculator.CreateNodeList();
            foreach (IExpr expr in this.pathList)
            {
                object result = expr.Evaluate(context);
                if (result is INodeList)
                {
                    INodeList resultNodeList = (INodeList)result;
                    foreach (object node in resultNodeList)
                    {
                        nodeList.Append(node);
                    }
                }
                else
                {
                    throw new ExprException("NodeList is expected.");
                }
            }
            return nodeList;
            //CID 0813 //2011.03.01 //End
        }

        //CID 0866 //2011.04.01 //Begin
        public void Visit(IExprVisitor visitor)
        {
            foreach (IExpr expr in this.pathList)
            {
                expr.Visit(visitor);
            }
        }
        //CID 0866 //2011.04.01 //End

        public void Print(StringBuilder buffer)
        {
            int index = 0;
            foreach (IExpr expr in this.pathList)
            {
                expr.Print(buffer);
                index++;
                if (index < this.pathList.Count)
                {
                    buffer.Append(" | ");
                }
            }
        }

        public static IExpr Parse(ExprParser parser)
		{
			IExpr pathExpr = PathExpr.Parse( parser );
			if( pathExpr != null )
			{
                List<IExpr> list = new List<IExpr>();
				list.Add( pathExpr );
				
				Token nextToken = parser.LookupNextToken(1);
				while( IsUnionOperator( nextToken ) )
				{
					parser.MoveNextIndex(1);

                    IExpr nextPathExpr = PathExpr.Parse(parser);
					if( nextPathExpr == null )
					{
						throw new Exception( "Cannot parse " + parser.XPath );
					}
					list.Add( nextPathExpr);
					
					nextToken = parser.LookupNextToken(1);
				}

                if (list.Count > 1)
                {
                    UnionExpr unionExpr = new UnionExpr();
                    unionExpr.pathList = list;
                    return unionExpr;
                }
                else
                {
                    return pathExpr;
                }
			}
			return null;
		}

		private static bool IsUnionOperator( Token token )
		{
			if( token != null )
			{
				if( token.Type.Equals( TokenType.Operator ) && token.Value.Equals( "|" ) )
				{
					return true;
				}
			}
			return false;
		}
	}
}
//CID 0164 //2008.12.13 //End
